const request = require('supertest');
const jwt = require('jsonwebtoken');
const app = require('../../app');

class ApiTestHelper {
  constructor() {
    this.app = app;
  }

  // 生成测试JWT Token
  generateToken(userId, role = 'user') {
    return jwt.sign(
      { id: userId, role },
      process.env.JWT_SECRET || 'test-secret',
      { expiresIn: '1h' }
    );
  }

  // 生成过期Token
  generateExpiredToken(userId, role = 'user') {
    return jwt.sign(
      { id: userId, role },
      process.env.JWT_SECRET || 'test-secret',
      { expiresIn: '-1h' } // 已过期
    );
  }

  // 创建认证请求
  authenticatedRequest(method, url, userId, role = 'user') {
    const token = this.generateToken(userId, role);
    return request(this.app)[method](url)
      .set('Authorization', `Bearer ${token}`);
  }

  // GET请求（带认证）
  get(url, userId, role = 'user') {
    return this.authenticatedRequest('get', url, userId, role);
  }

  // POST请求（带认证）
  post(url, userId, role = 'user') {
    return this.authenticatedRequest('post', url, userId, role);
  }

  // PUT请求（带认证）
  put(url, userId, role = 'user') {
    return this.authenticatedRequest('put', url, userId, role);
  }

  // DELETE请求（带认证）
  delete(url, userId, role = 'user') {
    return this.authenticatedRequest('delete', url, userId, role);
  }

  // 无认证请求
  noAuth() {
    return request(this.app);
  }

  // 测试API响应格式
  expectSuccessResponse(response, expectedData = null) {
    expect(response.body).toHaveProperty('success', true);
    if (expectedData) {
      expect(response.body).toHaveProperty('data');
      if (typeof expectedData === 'object') {
        expect(response.body.data).toMatchObject(expectedData);
      }
    }
  }

  // 测试API错误响应
  expectErrorResponse(response, expectedMessage = null) {
    expect(response.body).toHaveProperty('success', false);
    expect(response.body).toHaveProperty('message');
    if (expectedMessage) {
      expect(response.body.message).toContain(expectedMessage);
    }
  }

  // 测试分页响应
  expectPaginatedResponse(response) {
    this.expectSuccessResponse(response);
    expect(response.body.data).toHaveProperty('pagination');
    expect(response.body.data.pagination).toHaveProperty('current');
    expect(response.body.data.pagination).toHaveProperty('total');
    expect(response.body.data.pagination).toHaveProperty('pageSize');
    expect(response.body.data.pagination).toHaveProperty('totalItems');
  }

  // 测试API性能
  async measureApiPerformance(requestFunction, maxDuration = 2000) {
    const startTime = Date.now();
    const response = await requestFunction();
    const duration = Date.now() - startTime;

    console.log(`API响应时间: ${duration}ms`);
    expect(duration).toBeLessThan(maxDuration);

    return { response, duration };
  }

  // 并发测试
  async concurrentRequests(requestFunction, concurrency = 10) {
    const promises = Array(concurrency).fill().map(() => requestFunction());
    const results = await Promise.allSettled(promises);
    
    const successful = results.filter(r => r.status === 'fulfilled').length;
    const failed = results.filter(r => r.status === 'rejected').length;

    console.log(`并发测试结果: 成功 ${successful}, 失败 ${failed}`);

    return { successful, failed, results };
  }
}

module.exports = ApiTestHelper;